// systemInfo.js
const fs = require('fs');
const path = require('path');

class RemoteScriptInvoker {
    constructor(app, remote_id) {
        this.app = app;
        this.remote_id = remote_id;
    }

    async getSystemInfo() {
        let ssh_connected = await this.app.remotes.isSSHConnected(this.remote_id);
        if (!ssh_connected) {
            return null;
        }

        const script_path = path.join('$HOME/.labelapp/scripts/system_info.sh');
        try {
            let result = await this.app.remotes.execScript(this.remote_id, script_path);
            // console.log('getSystemInfo result = ', result);
            if (result.code == 0) {
                return JSON.parse(result.msg);
            } else {
                return null;
            }
        } catch (error) {
            console.error(error);
            return null;
        }
    }

    async getSoftwareInfo() {
        let ssh_conntected = await this.app.remotes.isSSHConnected(this.remote_id);
        if (!ssh_conntected) {
            return null;
        }

        const script_path = path.join('$HOME/.labelapp/scripts/software_info.sh');
        try {
            let result = await this.app.remotes.execScript(this.remote_id, script_path);
            // console.log('getSystemInfo result = ', result);
            if (result.code == 0) {
                return JSON.parse(result.msg);
            } else {
                return null;
            }
        } catch (error) {
            console.error(error);
            return null;
        }
    }

    async install() {
        let ssh_connected = await this.app.remotes.isSSHConnected(this.remote_id);
        if (!ssh_connected) {
            return null;
        }

        const script_path = path.join('$HOME/.labelapp/scripts/install_software.sh');
        try {
            let result = await this.app.remotes.execScript(this.remote_id, script_path);
            if (result.code == 0) {
                return true;
            } else {
                return null;
            }
        } catch (error) {
            console.error(error);
            return null;
        }
    }

    // 把各种shell脚本拷贝到远程服务器
    // 考虑是否要把libgl的安装也包含进来，需要执行两个命令
    // sudo apt-get update
    // sudo apt-get install -y libgl1-mesa-glx
    async init() {
        const localDir = path.join(__dirname, 'scripts');
        const remoteScriptsDir = '$HOME/.labelapp/scripts/';
        const versionFile = 'VERSION';

        try {
            // 检查远程 VERSION 文件
            let remoteVersion = '';
            try {
                remoteVersion = await this.app.remotes.execute(this.remote_id, `cat ${remoteScriptsDir}${versionFile}`);
                remoteVersion = remoteVersion.msg.trim();
            } catch (e) {
                console.log('Remote VERSION file not found, proceeding with upload.');
            }

            // 读取本地 VERSION 文件
            const localVersion = fs.readFileSync(path.join(localDir, versionFile), 'utf-8').trim();

            // 判断是否需要上传
            if (remoteVersion === localVersion) {
                console.log('Local and remote versions are the same. No upload needed.');
                return true;
            }

            // 远程服务器准备好目录
            await this.app.remotes.execute(this.remote_id, `mkdir -p ${remoteScriptsDir}`);

            // 读取scripts目录下的所有文件
            let scriptFiles = [];
            const items = fs.readdirSync(localDir);
            items.forEach((item) => {
                const fullPath = path.join(localDir, item);
                const stat = fs.statSync(fullPath);
                if (stat.isFile() && item.endsWith('.sh')) {
                    scriptFiles.push(fullPath);
                }
            });

            if (fs.existsSync(path.join(localDir, versionFile))) {
                scriptFiles.push(path.join(localDir, versionFile));
            }
            console.log(scriptFiles);

            // 上传所有的scripts到远程服务器
            for (let i = 0; i < scriptFiles.length; i++) {
                const scriptPath = scriptFiles[i];
                const remoteScriptPath = `${remoteScriptsDir}${path.basename(scriptPath)}`;
                let result = await this.app.remotes.execute(this.remote_id, `echo ${remoteScriptPath}`);
                await this.app.remotes.uploadFile(this.remote_id, scriptPath, result.msg.trim());
                if (scriptPath.endsWith('.sh')) {
                    await this.app.remotes.execute(this.remote_id, `chmod +x ${remoteScriptPath}`);
                }
            }

            return true;
        } catch (error) {
            console.error('RemoteLabelApp.init error:', error);
            return null;
        }
    }

    async start() {
        const script_path = path.join('$HOME/.labelapp/scripts/labelapp_start.sh');
        try {
            let result = await this.app.remotes.execScript(this.remote_id, script_path);
            if (result.code == 0) {
                return result.msg;
            } else {
                return null;
            }
        } catch (error) {
            console.error(error);
            return null;
        }
    }

    async stop() {
        const script_path = path.join('$HOME/.labelapp/scripts/labelapp_stop.sh');
        try {
            let result = await this.app.remotes.execScript(this.remote_id, script_path);
            if (result.code == 0) {
                return result.msg;
            } else {
                return null;
            }
        } catch (error) {
            console.error(error);
            return null;
        }
    }

    async version() {
        const script_path = path.join('$HOME/.labelapp/scripts/labelapp_version.sh');
        try {
            let result = await this.app.remotes.execScript(this.remote_id, script_path);
            if (result.code == 0) {
                return result.msg;
            } else {
                return null;
            }
        } catch (error) {
            console.error(error);
            return null;
        }
    }

    async monitor() {
        const monitorCommand = `pgrep -f "${this.installDirs.node}/bin/node start.js"`;
        try {
            const result = await this.app.remotes.execute(this.remote_id, monitorCommand);
            return result;
        } catch (error) {
            console.error('监控时出错:', error.message);
            return { code: -1, msg: '监控时出错' };
        }
    }
}

module.exports = { RemoteScriptInvoker };
